package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDto;
import com.sky.dto.SetmealPageDto;
import com.sky.entity.Category;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BusinessException;
import com.sky.exception.extend.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.ISetmealService;
import com.sky.vo.SetmealOverVo;
import com.sky.vo.SetmealPageVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional
public class SetmealServiceImpl implements ISetmealService {
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public int countSetmeals(Long categoryId) {
        return setmealMapper.countByCategoryId(categoryId);
    }

    @Override
    public void save(SetmealDto setmealDto) {
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(setmealDto,setmeal);
        setmeal.setStatus(StatusConstant.ENABLE);
        setmealMapper.save(setmeal);
        setmealDto.getSetmealDishes().forEach((item)->{
            item.setSetmealId(setmeal.getId());
        });
        setmealDishMapper.saveBatch(setmealDto.getSetmealDishes());
    }

    @Override
    public PageResult<SetmealPageVo> page(SetmealPageDto setmealPageDto) {
        PageHelper.startPage(setmealPageDto.getPage(),setmealPageDto.getPageSize());
        Page<Setmeal> setmealPage=setmealMapper.page(setmealPageDto);
        List<SetmealPageVo> collect = setmealPage.getResult().stream().map((item) -> {
            SetmealPageVo setmealPageVo = new SetmealPageVo();
            BeanUtils.copyProperties(item,setmealPageVo);
            String categoryName = categoryMapper.getById(item.getCategoryId());
            setmealPageVo.setCategoryName(categoryName);
            return setmealPageVo;
        }).collect(Collectors.toList());
        return new PageResult<>(setmealPage.getTotal(),collect);
    }

    @Override
    public SetmealOverVo getById(Long id) {
        //先查setmeal
       Setmeal setmeal=setmealMapper.getSetmealById(id);
       //在查categoryName;
        String categoryName=categoryMapper.getById(setmeal.getCategoryId());
        SetmealOverVo setmealOverVo=new SetmealOverVo();
        BeanUtils.copyProperties(setmeal,setmealOverVo);
        setmealOverVo.setCategoryName(categoryName);
        List<SetmealDish> setmealDishes=setmealDishMapper.getSetmealDishesBySetmealId(id);
        setmealOverVo.setSetmealDishes(setmealDishes);
        return setmealOverVo;
    }

    @Override
    public void modifyStatus(Integer status, Long id) {
        Setmeal setmeal = Setmeal.builder()
                .status(status)
                .id(id).build();
        setmealMapper.updateStatus(setmeal);
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        //坚持该套餐是否起售
        ids.forEach((id)->{
            Setmeal setmeal = setmealMapper.getSetmealById(id);
            if (Objects.equals(setmeal.getStatus(), StatusConstant.ENABLE)){
                throw new DeletionNotAllowedException("含有套餐"+MessageConstant.DELETE_NOT_ALLOWED);
            }
        });
        //由于该表的主键确实关联了订单，购物车。但是实际业务逻辑应该是当用户下单成功之后，无论商品是否停售还是已经被删除
        //商家必须给用户完成订单。所有我们只需操作setmealDish表即可。
        //当用户准备将购物车里的订单付款时，我们后端代码中，在进行回调，查询购物车里的订单是什么状态，如果已经被删除了，或者售空，我们
        //会给前端抛出业务异常后，自动将售空或者删除的商品给自动去除
        ids.forEach((id)->{
            setmealMapper.deleteById(id);
            setmealDishMapper.deleteBySetmealId(id);
        });
    }

    @Override
    public void modifySetmealWithDishes(SetmealDto setmealDto) {
        //
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(setmealDto,setmeal);
        setmealMapper.modifySetmeal(setmeal);
        //对setmeal表的操作可以为 先删除，再插入
        setmealDishMapper.deleteBySetmealId(setmeal.getId());
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes().stream().peek((item) -> {
            item.setSetmealId(setmeal.getId());
        }).collect(Collectors.toList());
        setmealDishMapper.saveBatch(setmealDishes);
    }

    @Override
    public List<Setmeal> list(Long categoryId) {
        return setmealMapper.list(categoryId);
    }
}
